const info = {
  name: 'Alice',
  age: 18,
  address: {
    city: 'beijing',
    country: 'china',
  },
};

// 循环引用
info.self = info;

function isObject(value) {
  const valueType = typeof value;
  return (
    valueType !== null && (valueType === 'object' || valueType === 'function')
  );
}

const betterDeepCopy = (obj, map = new WeakMap()) => {
  // 如果是Symbol类型，要创建一个新的Symbol
  if (typeof obj === 'symbol') return Symbol(obj.description);

  if (!isObject(obj)) return obj;

  // 如果是set类型
  if (obj instanceof Set) {
    const newSet = new Set();
    for (const setItem of obj) {
      newSet.add(betterDeepCopy(setItem, map));
    }
    return newSet;
  }

  // 如果是函数类型,一般是不需要进行深拷贝的
  if (typeof obj === 'function') return obj;

  if (map.get(obj)) return map.get(obj);
  const newObj = Array.isArray(obj) ? [] : {};
  map.set(obj, newObj);

  for (const key in obj) {
    newObj[key] = betterDeepCopy(obj[key], map);
  }

  return newObj;
};

const infoDeep = betterDeepCopy(info);

infoDeep.address.city = 'shanghai';
infoDeep.age = 0;
console.log('infoDeep', infoDeep);
console.log('info', info);
